import { CzmViewer } from 'xbsj-xe2/dist-node/xe2-cesium-objects';
import { bind } from 'xbsj-xe2/dist-node/xe2-base-utils';
import { Vector } from "xbsj-xe2/dist-node/xe2-math";
import { CzmESGeoVector, CzmESGeoWater, ESGeoPolygon, ESGeoWater } from 'esobjs-xe2-plugin/dist-node/esobjs-xe2-plugin-main';
import { ESMsWater } from '.';


export class CzmESMsWater extends CzmESGeoVector<ESMsWater> {
    static readonly type = this.register(ESMsWater.type, this);

    private _eSGeoWater = this.dv(new ESGeoWater());
    get eSGeoWater() { return this._eSGeoWater; }

    constructor(sceneObject: ESMsWater, czmViewer: CzmViewer) {
        super(sceneObject, czmViewer);
        const viewer = czmViewer.viewer;
        if (!viewer) {
            console.warn(`viewer is undefined!`);
            return;
        }
        const eSGeoWater = this.eSGeoWater;
        czmViewer.add(eSGeoWater);
        this.dispose(() => czmViewer.delete(eSGeoWater))

        //属性同步
        {
            this.d(bind([eSGeoWater, 'editing'], [sceneObject, 'editing']));
            this.d(bind([eSGeoWater, 'waterType'], [sceneObject, 'waterType']));
            this.d(bind([eSGeoWater, 'points'], [sceneObject, 'points']));
            this.d(bind([eSGeoWater, 'frequency'], [sceneObject, 'frequency']));
            this.d(bind([eSGeoWater, 'waveVelocity'], [sceneObject, 'waveVelocity']));
            this.d(bind([eSGeoWater, 'amplitude'], [sceneObject, 'amplitude']))
            this.d(bind([eSGeoWater, 'specularIntensity'], [sceneObject, 'specularIntensity']));
            this.d(bind([eSGeoWater, 'flowDirection'], [sceneObject, 'flowDirection']));
            this.d(bind([eSGeoWater, 'waterColor'], [sceneObject, 'waterColor']));
            this.d(bind([eSGeoWater, 'waterImage'], [sceneObject, 'waterImage']));
        }

        //显隐控制
        {
            const updateShow = () => {
                this.eSGeoWater.show = sceneObject.show;
            }
            updateShow();
            this.d(sceneObject.showChanged.don(() => { updateShow() }));
        }
        {
            const update = () => {
                //经纬度 转 Geojson
                const ArrayAdd = (arr: Iterable<unknown> | null | undefined) => {
                    let a = [...new Set(arr)] as [number, number, number][]; //去重加首尾相同
                    if (!Vector.equals(a[0], a[a.length - 1])) a.push(a[0]);
                    return [...a];
                }
                let GeoJsonArr = sceneObject.points;
                if (!GeoJsonArr || GeoJsonArr.length < 3) return;
                let tempPos = [];
                for (let index = 0; index < GeoJsonArr.length; index++) {
                    let el: any = GeoJsonArr[index];
                    tempPos.push([el[0], el[1], el[2] ?? 0]);
                }
                sceneObject.srcGeom = {
                    type: "Polygon",
                    coordinates: [ArrayAdd(tempPos)],
                };
            }
            update();
            this.ad(sceneObject.pointsChanged.don(update));
        }
    }
}